/*
 * ! Ext JS Library 3.0.0 Copyright(c) 2006-2009 Ext JS, LLC licensing@extjs.com
 * http://www.extjs.com/license
 */
/**
 * @class Ext.ux.GMapPanel
 * @extends Ext.Panel
 * @author Shea Frederick
 */
Ext.ux.GMapPanel = Ext.extend(Ext.Panel, {
	initComponent : function() {

		var defConfig = {
			plain : true,
			zoomLevel : 3,
			yaw : 180,
			pitch : 0,
			zoom : 0,
			gmapType : 'map',
			border : false
		};

		Ext.applyIf(this, defConfig);

		Ext.ux.GMapPanel.superclass.initComponent.call(this);

	},
	afterRender : function() {

		var wh = this.ownerCt.getSize();
		Ext.applyIf(this, wh);

		Ext.ux.GMapPanel.superclass.afterRender.call(this);

		if (this.gmapType === 'map') {
			this.gmap = new GMap2(this.body.dom);
		}

		if (this.gmapType === 'panorama') {
			this.gmap = new GStreetviewPanorama(this.body.dom);
		}

		if (typeof this.addControl == 'object' && this.gmapType === 'map') {
			this.gmap.addControl(this.addControl);
		}

		if (typeof this.setCenter === 'object') {
			if (typeof this.setCenter.geoCodeAddr === 'string') {
				this.geoCodeLookup(this.setCenter.geoCodeAddr);
			} else {
				if (this.gmapType === 'map') {
					var point = new GLatLng(this.setCenter.lat,
							this.setCenter.lng);
					this.gmap.setCenter(point, this.zoomLevel);
				}
				if (typeof this.setCenter.marker === 'object'
						&& typeof point === 'object') {
					this.addMarker(point, this.setCenter.marker,
							this.setCenter.marker.clear);
				}
			}
			if (this.gmapType === 'panorama') {
				this.gmap.setLocationAndPOV(new GLatLng(this.setCenter.lat,
								this.setCenter.lng), {
							yaw : this.yaw,
							pitch : this.pitch,
							zoom : this.zoom
						});
			}
		}

		GEvent.bind(this.gmap, 'load', this, function() {
					this.onMapReady();
				});

	},
	onMapReady : function() {
		this.addMarkers(this.markers);
		this.addMapControls();
		this.addOptions();
	},
	onResize : function(w, h) {

		if (typeof this.getMap() == 'object') {
			this.gmap.checkResize();
		}

		Ext.ux.GMapPanel.superclass.onResize.call(this, w, h);

	},
	setSize : function(width, height, animate) {

		if (typeof this.getMap() == 'object') {
			this.gmap.checkResize();
		}

		Ext.ux.GMapPanel.superclass.setSize.call(this, width, height, animate);

	},
	getMap : function() {

		return this.gmap;

	},
	getCenter : function() {

		return this.getMap().getCenter();

	},
	getCenterLatLng : function() {

		var ll = this.getCenter();
		return {
			lat : ll.lat(),
			lng : ll.lng()
		};

	},
	addMarkers : function(markers) {

		if (Ext.isArray(markers)) {
			for (var i = 0; i < markers.length; i++) {
				var mkr_point = new GLatLng(markers[i].lat, markers[i].lng);
				this.addMarker(mkr_point, markers[i].marker, false,
						markers[i].setCenter, markers[i].listeners);
			}
		}

	},
	addMarker : function(point, marker, clear, center, listeners) {

		Ext.applyIf(marker, G_DEFAULT_ICON);

		if (clear === true) {
			this.getMap().clearOverlays();
		}
		if (center === true) {
			this.getMap().setCenter(point, this.zoomLevel);
		}

		var mark = new GMarker(point, marker);
		if (typeof listeners === 'object') {
			for (evt in listeners) {
				GEvent.bind(mark, evt, this, listeners[evt]);
			}
		}
		this.getMap().addOverlay(mark);

	},
	addMapControls : function() {

		if (this.gmapType === 'map') {
			if (Ext.isArray(this.mapControls)) {
				for (i = 0; i < this.mapControls.length; i++) {
					this.addMapControl(this.mapControls[i]);
				}
			} else if (typeof this.mapControls === 'string') {
				this.addMapControl(this.mapControls);
			} else if (typeof this.mapControls === 'object') {
				this.getMap().addControl(this.mapControls);
			}
		}

	},
	addMapControl : function(mc) {

		var mcf = window[mc];
		if (typeof mcf === 'function') {
			this.getMap().addControl(new mcf());
		}

	},
	addOptions : function() {

		if (Ext.isArray(this.mapConfOpts)) {
			var mc;
			for (i = 0; i < this.mapConfOpts.length; i++) {
				this.addOption(this.mapConfOpts[i]);
			}
		} else if (typeof this.mapConfOpts === 'string') {
			this.addOption(this.mapConfOpts);
		}

	},
	addOption : function(mc) {

		var mcf = this.getMap()[mc];
		if (typeof mcf === 'function') {
			this.getMap()[mc]();
		}

	},
	geoCodeLookup : function(addr) {

		this.geocoder = new GClientGeocoder();
		this.geocoder.getLocations(addr, this.addAddressToMap
						.createDelegate(this));

	},
	addAddressToMap : function(response) {

		if (!response || response.Status.code != 200) {
			Ext.MessageBox.alert('Error', 'Code ' + response.Status.code
							+ ' Error Returned');
		} else {
			place = response.Placemark[0];
			addressinfo = place.AddressDetails;
			accuracy = addressinfo.Accuracy;
			if (accuracy === 0) {
				Ext.MessageBox.alert('Unable to Locate Address',
						'Unable to Locate the Address you provided');
			} else {
				if (accuracy < 7) {
					Ext.MessageBox
							.alert(
									'Address Accuracy',
									'The address provided has a low accuracy.<br><br>Level '
											+ accuracy
											+ ' Accuracy (8 = Exact Match, 1 = Vague Match)');
				} else {
					point = new GLatLng(place.Point.coordinates[1],
							place.Point.coordinates[0]);
					if (typeof this.setCenter.marker === 'object'
							&& typeof point === 'object') {
						this.addMarker(point, this.setCenter.marker,
								this.setCenter.marker.clear, true,
								this.setCenter.listeners);
					}
				}
			}
		}

	}

});

Ext.reg('gmappanel', Ext.ux.GMapPanel);